<template>
  <div class="bpmn-editor">
    <!-- 工具栏 -->
    <div class="toolbar">
      <button @click="addElement('task')">添加任务</button>
      <button @click="addElement('event')">添加事件</button>
      <button @click="addElement('gateway')">添加网关</button>
      <button @click="toggleLineMode">连线模式</button>
    </div>

    <!-- 画布 -->
    <div class="canvas-container"
         @mousedown="onMouseDown"
         @mousemove="onMouseMove"
         @mouseup="onMouseUp"
         @mouseleave="onMouseLeave">
      <canvas ref="canvasRef" width="800" height="600"></canvas>
    </div>

    <!-- 属性面板（浮动在右侧） -->
    <div v-if="selectedElement" class="property-panel">
      <h3>属性编辑</h3>
      <div>
        <label for="name">名称：</label>
        <input v-model="selectedElement.name" id="name" />
      </div>
      <div>
        <label for="type">类型：</label>
        <input v-model="selectedElement.type" id="type" />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue';

const canvasRef = ref(null);
const ctx = ref(null);
const elements = reactive([]);
const lines = reactive([]);
const selectedElement = ref(null);
const isDragging = ref(false);
const isLineMode = ref(false);
const currentLine = reactive({ start: null, end: null });
const mousePosition = reactive({ x: 0, y: 0 });
const elementMargin = 20; // 元素之间的间距

onMounted(() => {
  if (canvasRef.value) {
    ctx.value = canvasRef.value.getContext('2d');
    drawElements();
  }
});

const addElement = (type) => {
  let xPos = 50;
  let yPos = 50;

  // 如果已有元素，放置在最后一个元素的右边
  if (elements.length > 0) {
    const lastElement = elements[elements.length - 1];
    xPos = lastElement.x + lastElement.width + elementMargin; // 新元素在当前元素右边
    yPos = lastElement.y; // 纵坐标不变，保持在同一水平线上
  }

  const newElement = {
    id: Date.now(),
    name: `${type} 元素`,
    type,
    x: xPos,
    y: yPos,
    width: 100,
    height: 50,
    color: type === 'task' ? 'blue' : type === 'event' ? 'green' : 'orange',
    borderStyle: 'solid',
    selected: false // 初始时未选中
  };

  elements.push(newElement);
  drawElements();
};

const toggleLineMode = () => {
  isLineMode.value = !isLineMode.value;
  if (!isLineMode.value) {
    currentLine.start = null;
    currentLine.end = null;
  }
};

const drawElements = () => {
  if (ctx.value) {
    ctx.value.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height);

    // 绘制连线
    lines.forEach((line) => {
      const source = elements.find((el) => el.id === line.source);
      const target = elements.find((el) => el.id === line.target);
      if (source && target) {
        ctx.value.beginPath();
        ctx.value.moveTo(source.x + source.width / 2, source.y + source.height / 2);
        ctx.value.lineTo(target.x + target.width / 2, target.y + target.height / 2);
        ctx.value.stroke();
      }
    });

    // 绘制元素
    elements.forEach((element) => {
      // 如果是选中的元素，背景颜色改变
      ctx.value.fillStyle = element.selected ? 'lightblue' : element.color;
      ctx.value.fillRect(element.x, element.y, element.width, element.height);

      // 如果是选中的元素，边框变成虚线
      ctx.value.lineWidth = 2;
      ctx.value.strokeStyle = 'black';
      ctx.value.setLineDash(element.selected ? [5, 5] : []);  // 选中时设置虚线
      ctx.value.strokeRect(element.x, element.y, element.width, element.height);
      ctx.value.fillStyle = 'white';
      ctx.value.fillText(element.name, element.x + 10, element.y + 20);
    });

    // 绘制正在绘制的连线
    if (currentLine.start) {
      const startElement = elements.find((el) => el.id === currentLine.start);
      if (startElement) {
        ctx.value.beginPath();
        ctx.value.moveTo(startElement.x + startElement.width / 2, startElement.y + startElement.height / 2);
        ctx.value.lineTo(mousePosition.x, mousePosition.y);
        ctx.value.stroke();
      }
    }
  }
};

const onMouseDown = (event) => {
  const { offsetX: x, offsetY: y } = event;

  // 如果是连线模式
  if (isLineMode.value) {
    const startElement = elements.find((element) => x > element.x && x < element.x + element.width && y > element.y && y < element.y + element.height);
    if (startElement) {
      currentLine.start = startElement.id;
    }
  } else {
    // 单击选择元素并改变背景色和边框
    elements.forEach((element) => {
      if (x > element.x && x < element.x + element.width && y > element.y && y < element.y + element.height) {
        // 选中元素时，更新选中状态并清除其他元素的选中状态
        if (selectedElement.value !== element) {
          if (selectedElement.value) {
            selectedElement.value.selected = false;  // 取消选中之前的元素
          }
          selectedElement.value = element;
          element.selected = true;
        }
      } else {
        // 如果不在元素上点击，清除选中状态
        element.selected = false;
      }
    });
  }
  drawElements();  // 重新绘制以更新样式
};

const onMouseMove = (event) => {
  const { offsetX: x, offsetY: y } = event;

  if (currentLine.start) {
    mousePosition.x = x;
    mousePosition.y = y;
    drawElements();
  }
};

const onMouseUp = () => {
  if (currentLine.start) {
    const endElement = elements.find((element) => mousePosition.x > element.x && mousePosition.x < element.x + element.width && mousePosition.y > element.y && mousePosition.y < element.y + element.height);
    if (endElement && endElement.id !== currentLine.start) {
      lines.push({ source: currentLine.start, target: endElement.id });
    }
    currentLine.start = null;
    drawElements();
  }
};

const onMouseLeave = () => {
  if (currentLine.start) {
    currentLine.start = null;
    drawElements();
  }
};
</script>

<style scoped>
.bpmn-editor {
  display: flex;
  flex-direction: column;
}

.toolbar {
  margin: 10px;
}

.canvas-container {
  position: relative;
}

.property-panel {
  position: absolute;
  top: 50px;
  right: 10px;
  width: 200px;
  padding: 20px;
  background: #f4f4f4;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.property-panel input {
  width: 100%;
}

canvas {
  border: 1px solid #ccc;
}
</style>
